package org.tinygroup.weblayer;

import static org.tinygroup.weblayer.webcontext.parser.ParserWebContext.DEFAULT_CHARSET_ENCODING;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.weblayer.webcontext.parser.ParserWebContext;
import org.tinygroup.weblayer.webcontext.util.QueryStringParser;
import org.tinygroup.weblayer.webcontext.util.WebContextUtil;

/**
 * weblayer集成的HttpServlet，内部封装多个TinyProcessor,委派处理器去执行
 * 
 * @author renhui
 *
 */
public class TinyHttpServlet extends HttpServlet {

	private TinyProcessorManager tinyProcessorManager;

	private static final Logger LOGGER = LoggerFactory
			.getLogger(TinyHttpServlet.class);
	private static final String SEARCH_STR = "?";

	@Override
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		WebContext webContext = WebContextUtil.getWebContext(request);
		String servletPath = getServletPath(request, webContext);
		if (!tinyProcessorManager.execute(servletPath, webContext)) {
			throw new ServletException(String.format(
					"未找到请求路径：%s，对应的TinyProcessor", servletPath));
		}
	}

	private String getServletPath(HttpServletRequest request,
			WebContext webContext) {
		String servletPath = (String) request
				.getAttribute(TinyHttpFilter.DEFAULT_PAGE_KEY);
		if (StringUtil.isBlank(servletPath)) {
			servletPath = request.getServletPath();
			if (StringUtil.isBlank(servletPath)) {
				servletPath = request.getPathInfo();
			}
			if (StringUtil.isBlank(servletPath)) {// 兼容tomcat8的处理情况，如果servletPath为空，设置为"/"
				servletPath = "/";
			}
		}
		if (StringUtil.contains(servletPath, SEARCH_STR)) {
			parserRequestPath(servletPath, request, webContext);
		}
		return StringUtil.substringBefore(servletPath, SEARCH_STR);
	}

	/**
	 * 解析请求路径servletPath的参数信息，把参数信息存放在上下文中
	 *
	 * @param request
	 * @param servletPath
	 */
	private void parserRequestPath(String servletPath,
			HttpServletRequest request, final WebContext webContext) {
		ParserWebContext requestContext = WebContextUtil.findWebContext(
				request, ParserWebContext.class);
		String charset = requestContext.isUseBodyEncodingForURI() ? request
				.getCharacterEncoding() : requestContext.getURIEncoding();
		QueryStringParser parser = new QueryStringParser(charset,
				DEFAULT_CHARSET_ENCODING) {
			protected void add(String key, String value) {
				webContext.put(key, value);
			}
		};
		parser.parse(StringUtil.substringAfter(servletPath, SEARCH_STR));
	}

	public void init(ServletConfig filterConfig) throws ServletException {
		LOGGER.logMessage(LogLevel.INFO, "tinyHttpServlet初始化开始...");

		initTinyProcessors();

		LOGGER.logMessage(LogLevel.INFO, "tinyHttpServlet初始化结束...");
	}

	/**
	 * tiny-processors初始化
	 *
	 * @throws IOException
	 * @throws ServletException
	 */
	private void initTinyProcessors() throws ServletException {
		tinyProcessorManager = BeanContainerFactory.getBeanContainer(
				this.getClass().getClassLoader()).getBean(
				TinyProcessorManager.TINY_PROCESSOR_MANAGER);
		tinyProcessorManager.initTinyResources();
	}

	/**
	 * 销毁tiny-processors
	 */
	private void destroyTinyProcessors() {
		tinyProcessorManager.destoryTinyResources();
	}

	public void destroy() {
		destroyTinyProcessors();
	}
}
